/**
 * Copyright (C) 2009-2012 Couchbase, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
 * IN THE SOFTWARE.
 */

package net.crawwle.career.analyze.couchbase;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Properties;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.Logger;
import org.elasticsearch.client.Client;
import org.elasticsearch.node.Node;
import org.elasticsearch.node.NodeBuilder;

import com.couchbase.client.CouchbaseClient;

/**
 * The ConnectionManager handles connecting, disconnecting and managing of the
 * Couchbase connection.
 *
 * To get the connection from a Servlet context, use the getInstance() method.
 */
public class ConnectionManager implements ServletContextListener {

	/**
	 * Holds the connected Couchbase instance.
	 */
	private static CouchbaseClient client;

	/**
	 * Holds the connected Couchbase instance.
	 */
	private static CouchbaseClient clientKeyword;

	/**
	 * Holds  ElasticSearch Cluster Name.
	 */
	private static String esCluster ;


	private static Node esNode = null;

	private static Client esClient = null;

	/**
	 * @return esNode
	 */
	public static Node getEsNode() {
		return esNode;
	}

	/**
	 * @param esNode セットする esNode
	 */
	public static void setEsNode(Node esNode) {
		ConnectionManager.esNode = esNode;
	}

	/**
	 * @return esClient
	 */
	public static Client getEsClient() {
		return esClient;
	}

	/**
	 * @param esClient セットする esClient
	 */
	public static void setEsClient(Client esClient) {
		ConnectionManager.esClient = esClient;
	}

	/**
	 * The Logger to use.
	 */
	private static final Logger logger = Logger
			.getLogger(ConnectionManager.class.getName());

	/**
	 * @return esCluster
	 */
	public static String getEsCluster() {
		return esCluster;
	}

	/**
	 * @param esCluster セットする esCluster
	 */
	public static void setEsCluster(String esCluster) {
		ConnectionManager.esCluster = esCluster;
	}

	/**
	 * Connect to Couchbase when the Server starts.
	 *
	 * @param sce
	 *            the ServletContextEvent (not used here).
	 */
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		logger.info("Connecting to Couchbase Cluster");


		// Proxyサーバ
		Properties conf = new Properties();
		//InputStream inputStream = this.getClass().getClassLoader()
		//		.getResourceAsStream("crawwle.properties");
		try {
			InputStream inputStream = new FileInputStream("/opt/conf/crawwle.properties");
			conf.load(inputStream);

			ArrayList<URI> nodes = new ArrayList<URI>();
			nodes.add(URI.create(conf.getProperty("coubase.server.node.url")));
			client = new CouchbaseClient(nodes, conf.getProperty(
					"coubase.server.bucket.career"), "");
			clientKeyword = new CouchbaseClient(nodes, conf.getProperty(
					"coubase.server.bucket.keyword"), "");
			esCluster = conf.getProperty("elastic.search.cluster");

			esNode = NodeBuilder.nodeBuilder().node();
			esClient = esNode.client();
			inputStream.close();
		} catch (IOException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();

			logger.error("the crawwle.properties file does not exist.");
			//return;
		} catch (Exception e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();

			logger.error(e.getMessage());
			//return;
		}

		/*
		 * ResourceBundle bundle = ResourceBundle.getBundle("crawwle");
		 * ArrayList<URI> nodes = new ArrayList<URI>();
		 * nodes.add(URI.create(bundle
		 * .getObject("coubase.server.node.url").toString())); try { client =
		 * new CouchbaseClient(nodes,
		 * bundle.getObject("coubase.server.bucket.career").toString(), "");
		 * clientKeyword = new CouchbaseClient(nodes,
		 * bundle.getObject("coubase.server.bucket.keyword").toString(), ""); }
		 * catch (IOException ex) { logger.log(Level.SEVERE, ex.getMessage()); }
		 */

	}

	public static void reConnect(String url,String career,String keyword,String cluster) throws Exception {
		logger.info("ReConnecting to Couchbase Cluster");


		CouchbaseClient client1,client2;

		try {

			ArrayList<URI> nodes = new ArrayList<URI>();
			nodes.add(URI.create(url));
			client1 = new CouchbaseClient(nodes, career, "");
			client2 = new CouchbaseClient(nodes,keyword, "");
		} catch (Exception e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();

			logger.error("接続エラー.");
			throw e;
		}

		if(client != null){
			client.shutdown();
		}
		if(clientKeyword != null){
			clientKeyword.shutdown();
		}
		client = client1;
		clientKeyword = client2;
		esCluster = cluster;
	}


	/**
	 * Disconnect from Couchbase when the Server shuts down.
	 *
	 * @param sce
	 *            the ServletContextEvent (not used here).
	 */
	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		logger.info("Disconnecting from Couchbase Cluster");
		if(client != null){
			client.shutdown();
		}
		if(clientKeyword != null){
			clientKeyword.shutdown();
		}
		if (this.esClient != null) {
			esClient.close();
		}
		if (this.esNode != null) {
			esNode.close();
		}
	}

	/**
	 * Returns the current CouchbaseClient object.
	 *
	 * @return the current Couchbase connection.
	 */
	public static CouchbaseClient getInstance() {
		return client;
	}

	/**
	 * Returns the current CouchbaseClient object.
	 *
	 * @return the current Couchbase connection.
	 */
	public static CouchbaseClient getKeywordInstance() {
		return clientKeyword;
	}

}
